<?php

namespace App\Service\CommodityService;

use App\Service\BaseService;
use App\Service\InterfaceService\WebSocketInterface;
use App\Service\Code\Normal;
use App\Model\CommodityModel\Stockinfo;
use Hyperf\DbConnection\Db;
use App\Model\CommodityModel\CommodityOptimizationBbc;
use Service\AppService\IdService;
use App\Model\CommodityModel\SupplierCommodityTag;
use App\Service\AuthService\ManageWsUserAuthService;
use App\Model\PssModel\Business;
use Hyperf\Utils\WaitGroup;
use Hyperf\Task\Annotation\Task;
use App\Model\PssModel\Sysconfig;

class CommodityOptimizationService extends BaseService implements WebSocketInterface
{
    const GOODS_SETTING_MODE_BASE       = 1;//基础配置
    const GOODS_SETTING_MODE_ADVANCE    = 2;//高级配置
    const SUPPLIER_CHOICE_MODE_WH       = 1;//指定供应商
    const SUPPLIER_CHOICE_MODE_SP       = 2;//指定商品
    const PAGE_LIMIT                    = 500;
    
    //是否指定商品导入
    protected $IsImportGoods        = false;
    //是否有库存范围限制
    protected $IsStockNumberLimit   = false;
    //是否有校期限制
    protected $IsGoodsExpireLimit   = false;
    
    /**
     * 接收websocket消息
     */
    public function onMessage($server,$frame)
    {
        $paramters      = @json_decode($frame->data,true);
        $res            = $this->checkLogin($paramters);
        if( $res['code'] != Normal::SUC ) {
            $send = Normal::returnCode(Normal::WS_ERROR,$res['msg']);
            return $server->push($frame->fd,json_encode($send,JSON_UNESCAPED_UNICODE));
        }
        
        $systemUser     = $res['data'];
        $receive_data   = $paramters['requestData'];
        $bid            = $receive_data['bid'];
        
        //检查请求参数
        $resQueryParam  = $this->getWhereParameters($receive_data);
        if( $resQueryParam['code'] != Normal::SUC ) {
            $send = Normal::returnCode(Normal::WS_ERROR,$resQueryParam['msg']);
            return $server->push($frame->fd,json_encode($send,JSON_UNESCAPED_UNICODE));
        }
        
        //开始处理查询规则
        $where          = $resQueryParam['data'];
        
        //是否立即保存并且授权
        if( isset($receive_data['AuthGoodsType']) && $receive_data['AuthGoodsType'] == 1 ) 
        {
            //渠道商户
            if( $bid > 0 ) 
            {
                $businfo = Business::instance()->info(['id'=>$bid]);
                //是否初次授权
                if( $businfo['has_template'] != 1) {
                    $send = Normal::returnCode(Normal::WS_ERROR,'当前商户初次授权商品，不允许直接操作保存并且授权，需要进入下一步进行价格模板设置！');
                    return $server->push($frame->fd,json_encode($send,JSON_UNESCAPED_UNICODE));
                }
            
                //是否正在授权商品中
                if( $businfo['sync_status'] == 2 ) {
                    $send = Normal::returnCode(Normal::WS_ERROR,'当前商户正在同步授权商品，请耐心等候！');
                    return $server->push($frame->fd,json_encode($send,JSON_UNESCAPED_UNICODE));
                }
            } else {
                //商城模板
                $info = Sysconfig::instance()->getShopTemplate();
                if( empty($info) || empty($info['contents']) ) {
                    $send = Normal::returnCode(Normal::WS_ERROR,'当前商户初次授权商品，不允许直接操作保存并且授权，需要进入下一步进行价格模板设置！');
                    return $server->push($frame->fd,json_encode($send,JSON_UNESCAPED_UNICODE));
                }
                
                //正在授权
                if( $info['value'] == 1 ) {
                    $send = Normal::returnCode(Normal::WS_ERROR,'当前商户正在同步授权商品，请耐心等候！');
                    return $server->push($frame->fd,json_encode($send,JSON_UNESCAPED_UNICODE));
                }
            }
        }
        
        //对接请求参数规则
        $receive_data['sys_user_id'] = $systemUser['id'];
        $clientInfo     = $server->getClientInfo($frame->fd);
        $json = json_encode($receive_data,JSON_UNESCAPED_UNICODE);
        $log = ["content"=>"操作优选规则【{$json}】","ip"=>$clientInfo['remote_ip']??'0.0.0.0','sys_user_id'=>$systemUser['id'],'sys_user_name'=>$systemUser['name']];
        ManageWsUserAuthService::instance()->addSystemLog($log);
        
        //渠道商户
        if( $bid > 0 )
        {
            $businfo = Business::instance()->getUserInfoByBid($bid);
        
            if( $businfo['sync_mode'] == 1 ) {
                $send = Normal::returnCode(Normal::WS_ERROR,'请勿重复点击，当前优选规正在处理中');
                Business::instance()->where('id',$bid)->update(['sync_mode'=>0]);
                return $server->push($frame->fd,json_encode($send,JSON_UNESCAPED_UNICODE));
            }
        
            //下游bbc渠道保持资料完整
            if( $businfo['is_router_user'] != 1 ) {
                $where['baseWhere'][] = "com.IsIntegrity =1";
            }
        
            Business::instance()->where('id',$bid)->update(['sync_mode'=>1]);
        } else {
            //商城模板保持资料完整
            $where['baseWhere'][] = "com.IsIntegrity =1";
        
            //商城模板
            $info = Sysconfig::instance()->getShopTemplate();
            if( $info['small_type'] == 1 ) {
                $send = Normal::returnCode(Normal::WS_ERROR,'请勿重复点击，当前优选规正在处理中');
                Sysconfig::instance()->where('id',$info['id'])->update(['small_type'=>0]);
                return $server->push($frame->fd,json_encode($send,JSON_UNESCAPED_UNICODE));
            }
        
            Sysconfig::instance()->where('id',$info['id'])->update(['small_type'=>1]);
        }
        
        //获取子查询
        $subQuery       = $this->getBestGoodsQuery($bid,$where,$receive_data);
        //获取数据总条数
        $totalCount     = $this->getBestGoodsCountBySubQuery($subQuery,$receive_data);
        if( $totalCount <= 0 ) {
            $send = Normal::returnCode(Normal::WS_ERROR,"当前优选授权规则条件下,未找到满足条件的数据，请核对优选规则是否正确！");
            return $server->push($frame->fd,json_encode($send,JSON_UNESCAPED_UNICODE));
        }
        
        //开始分页写入数据
        $pageCount = ceil($totalCount/self::PAGE_LIMIT);
        
        //重置IsInit
        CommodityOptimizationBbc::instance()->getTableByBuID($bid)->where('BuID',$bid)->update([
            'IsInit' => 0,
        ]);
        
        for( $page = 1 ; $page <= $pageCount ; $page ++ )
        {
            $pageList = $this->getBestGoodsPageList($bid,$subQuery,$page,self::PAGE_LIMIT);
            if( !empty($pageList['data']) ) 
            {
                $dataList = $pageList['data'];
                foreach ($dataList as $key => & $value)
                {
                    //如果当前锁仓库存大于0，则当前渠道用户对应商品批次数据，肯定是有数据
                    if( $value['StockRemainNumber'] <= 0 && $value['Number'] <= 0 && $value['NumberLock'] > 0 ) {
                        unset($dataList[$key]);
                        continue;
                    }
                    
                    $value['ID']            = IdService::instance()->getOtherID();
                    $value['BuID']          = $receive_data['bid'];
                    $value['IsInit']        = 1;
                    $SaleFirstSupplierlist  = $receive_data['GoodsAdvanceSettings']['SaleFirstSupplierlist'] ?? [] ;
                    $value['IsSaleFirst']   = !empty($SaleFirstSupplierlist) && in_array($value['SupplierCompanyID'], $SaleFirstSupplierlist) ? 1 : 0 ;
                    $value['CreateTime']    = date("Y-m-d H:i:s");
                    $value['CommodityStatus'] = 1;
                    
                    if( isset($value['SupplierCompanyID']) ) {unset($value['SupplierCompanyID']);}
                    if( isset($value['StockRemainNumber']) ) {unset($value['StockRemainNumber']);}
                    if( isset($value['Number']) ) {unset($value['Number']);}
                    if( isset($value['NumberLock']) ) {unset($value['NumberLock']);}
                }
                
                if( empty($dataList) ) {
                    continue;
                }
                
                //开始处理数据库
                $res = $this->CommodityOptimizationWrite($bid,$dataList);
                if( $res['code'] != Normal::WS_START ) {
                    return $server->push($frame->fd,json_encode($res,JSON_UNESCAPED_UNICODE));
                }
            }
            
            if ( $page == $pageCount ) {
                $percent = '100.00';//最后一页数据处理
            } else {
                $percent = bcdiv($page, $pageCount, 4);
                $percent = bcmul($percent, 100, 2);
            }
            
            $send = Normal::returnCode(Normal::WS_START, "进行中", [
                'percent' => $percent
            ]);
            $server->push($frame->fd,json_encode($send,JSON_UNESCAPED_UNICODE));
        }
        
        //写入优选商品池数据完成之后，更新当前渠道优选规则
        $template = json_encode($receive_data,JSON_UNESCAPED_UNICODE);
        if( $bid > 0 ) {
            $updateBus = [
                'template'              => $template,
                'has_template'          => 1,
                'template_update_time'  => time(),
                'is_goods_expire'       => $this->IsGoodsExpireLimit ? 1 : 0,
                'is_stock_limit'        => $this->IsStockNumberLimit ? 1 : 0,
                'is_import_goods'       => $this->IsImportGoods ? 1 : 0,
                'sync_mode'             => 0,
            ];
            
            //保存立即授权
            if( isset($receive_data['AuthGoodsType']) && $receive_data['AuthGoodsType'] == 1 ) {
                $updateBus['is_sync']   = 1;
                $updateBus['sync_type'] = 1;
                $updateBus['sync_status'] = 0;
            }
            
            $this->IsImportGoods = false;
            $this->IsGoodsExpireLimit = false;
            $this->IsStockNumberLimit = false;
            
            //更新优选规则
            Business::instance()->where('id',$bid)->update($updateBus);
        } else {
            //保存立即授权
            $is_sync = false;
            if( isset($receive_data['AuthGoodsType']) && $receive_data['AuthGoodsType'] == 1 ) {
                $is_sync = true;
            }
            Sysconfig::instance()->updateContents($template,$is_sync);
        }
        
        //处理结束
        $send = Normal::returnCode(Normal::WS_END, "处理结束", [
            'percent' => $percent
        ]);
        $server->push($frame->fd,json_encode($send,JSON_UNESCAPED_UNICODE));
    }
    
    /**
     * 增量更新优选池数据
     * @Task
     * @param array $receive_data
     */
    public function getUserSkuIDChange( $param = [] )
    {
        if( empty($param['bids']) ) {
            return Normal::returnCode(Normal::FAIL,"用户bids组不能为空");
        }
        
        if( empty($param['SkuIDS']) && empty($param['SupplierSKUIDS'])) {
            return Normal::returnCode(Normal::FAIL,"商品数据SkuIDS或者供应商商品SupplierSKUIDS不能为空");
        }
        
        $bids = $param['bids'];
        $bids = array_unique($bids);
        if( empty($bids) ) {
            return Normal::returnCode(Normal::FAIL,"用户IDs组不能为空");
        }
        
        //商城模板
        if( in_array('0', $bids) && count($bids) == 1 ) {
            $shopTemplate = Sysconfig::instance()->getShopTemplate();
            $busList = [
                [
                    'id'       => 0,
                    'template'  => $shopTemplate['contents']
                ]
            ];
        } else {
            $busList = Business::instance()->getUserInfoTemplatesByBids($bids);
        }
        
        $result = [];
        $count = count($busList);
        $wg = new \Hyperf\Utils\WaitGroup();
        $wg->add($count);
        foreach ($busList as $binfo )
        {
            co(function () use ($wg,$binfo,$param,& $result ) 
            {
                $receive_data   = @json_decode($binfo['template'],true);
                if( !empty($param['SkuIDS']) ) {
                    $receive_data['SkuIDS'] = $param['SkuIDS'];
                }
        
                if( !empty($param['SupplierSKUIDS']) ) {
                    $receive_data['SupplierSKUIDS'] = $param['SupplierSKUIDS'];
                }
                
                $bid = $binfo['id'];
                $resQueryParam  = $this->getWhereParameters($receive_data);
                if( $resQueryParam['code'] != Normal::SUC ) {
                    $result[$bid] = $resQueryParam;
                } else {
                    $where = $resQueryParam['data'];
                    
                    //商城模板或者下游bbc渠道保持资料完整
                    if( $bid == 0 || (isset($binfo['is_router_user']) && $binfo['is_router_user'] != 1) ) {
                        $where['baseWhere'][] = "com.IsIntegrity=1";
                    }
                    
                    //获取子查询
                    $subQuery = $this->getBestGoodsQuery($bid,$where,$receive_data);
                    $goodsList = $this->getBestGoodsList($bid,$subQuery);
                    $result[$bid] = Normal::returnCode(Normal::SUC,"获取成功",$goodsList);
                }
                $wg->done();
            });
        }
        $wg->wait();
        return Normal::returnCode(Normal::SUC,"处理成功",$result);        
    }
    
    /**
     * 处理优选表数据
     * @return mixed
     */
    public function CommodityOptimizationWrite($bid, $dataList = [] )
    {
        $supplierSkuIDList = array_column($dataList,null,'SupplierSKUID');
        $columns = ['ID','SupplierSKUID'];
        $hasList = CommodityOptimizationBbc::instance()->getTableByBuID($bid)->where('BuID',$bid)->whereIn('SupplierSKUID',array_keys($supplierSkuIDList))->get()->toArray();
        try {
        
            CommodityOptimizationBbc::instance()->getTableByBuID($bid)->startTrans();
            
            //如果存在需要更新的数据
            if( $hasList ) {
                
                //需要更新的字段
                $updateSqlColumns = [
                    'SkuID',
                    'SKUCode',
                    'SupplierSKUCode',
                    'BatchNo',
                    'StockInfoID',
                    'BatchSpecMinSinglePrice',
                    'SpecList',
                    'IsInit',
                    'IsSaleFirst',
                    'UpdateTime',
                    'PriceRuleType',
                    'IsPriceSet',
                    'CommodityStatus'
                ];
                
                foreach ($hasList as $key => $item ) 
                {
                    //防止重复的数据
                    if( ! isset($supplierSkuIDList[$item['SupplierSKUID']]) ) 
                    {
                        //需删除当前重复的那一条数据
                        CommodityOptimizationBbc::instance()->getTableByBuID($bid)->where('ID',$item['ID'])->delete();
                        unset($hasList[$key]);
                        continue;
                    }
                    
                    //如果存在数据并且和当前优选商品SKU一直则更新
                    $postData = $supplierSkuIDList[$item['SupplierSKUID']];
                    foreach ($updateSqlColumns as $column)
                    {
                        if( $column == 'UpdateTime' ) {
                            $then  = date("Y-m-d H:i:s");
                        } else if( in_array($column, ['IsPriceSet','PriceRuleType']) ) {
                            $then = '0';
                        } else {
                            $then  = $postData[$column];
                        }
                        ${$column}[] = "WHEN {$item['ID']} THEN '{$then}'";
                    }
                    unset($supplierSkuIDList[$item['SupplierSKUID']]);
                }
                
                //如果有存在更新的数据
                if( $hasList ) {
                    $whenSql = [];
                    foreach ($updateSqlColumns as $column)
                    {
                        $whenSql[] = "{$column} = CASE ID " .(implode(" ", ${$column})) . " END";
                    }
                    $whenBatchUpdateSql = implode(",", $whenSql);
                    $whereIds = implode(",", array_column($hasList,'ID'));
                    
                    //批量更新数据
                    $databaseName   = CommodityOptimizationBbc::instance()->getTableByBuID($bid)->getConnection()->getDatabaseName();
                    $tableName      = CommodityOptimizationBbc::instance()->getTableByBuID($bid)->getTable();
                    $sql_batch_sql  = "UPDATE `{$databaseName}`.`{$tableName}` SET {$whenBatchUpdateSql} WHERE ID IN({$whereIds})";
                    Db::connection('net_commodity')->update($sql_batch_sql);
                }
            }
            
            //如果存在新增的数据
            if( $supplierSkuIDList ) {
                CommodityOptimizationBbc::instance()->getTableByBuID($bid)->insert($supplierSkuIDList);
            }
            
            CommodityOptimizationBbc::instance()->getTableByBuID($bid)->commit();
            return Normal::returnCode(Normal::WS_START,"处理成功");
        } catch ( \Throwable $th ) {
            CommodityOptimizationBbc::instance()->getTableByBuID($bid)->rollback();
            return Normal::returnCode(Normal::WS_ERROR,$th->getMessage(),[
                'errorFile' => $th->getFile(),
                'errorLine' => $th->getLine()    
            ]);
        }
    }
    
    /**
     * 获取优选池字段
     * @return mixed
     */
    public function getGoodsColumns()
    {
        return [
            Db::raw("outter_com.ID AS SkuID"),
            Db::raw("outter_com.SKUCode"),
            Db::raw("outter_scb.SupplierCommoditySkuCode AS SupplierSKUCode"),
            Db::raw("CONCAT(outter_scb.ID,'') AS SupplierSKUID"),
            Db::raw("CONCAT(outter_stb.ID,'') AS StockInfoID"),
            Db::raw("outter_stb.BatchNo"),
            Db::raw("CONCAT(outter_stb.SupplierCompanyID,'') as SupplierCompanyID"),
            "outter_stb.BatchSpecMinSinglePrice",
            "outter_stb.SpecList",
            Db::raw("outter_stb.Number"),
            Db::raw("outter_stb.NumberLock"),
            Db::raw("IFNULL(u_stock.StockRemainNumber,0) AS StockRemainNumber"),
        ];
    }
    
    /**
     * 获取增量更新字段
     * @return mixed
     */
    public function getNotifyChangeGoodsColumns()
    {
        return [
            Db::raw("CONCAT(outter_com.ID,'') AS SkuID"),
            Db::raw("CONCAT(outter_com.SKUCode,'') AS SKUCode"),
            Db::raw("CONCAT(outter_scb.SupplierCommoditySkuCode,'') AS SupplierSKUCode"),
            Db::raw("CONCAT(outter_scb.ID,'') AS SupplierSKUID"),
            Db::raw("CONCAT(outter_stb.ID,'') AS StockInfoID"),
            Db::raw("CONCAT(outter_stb.SupplierCompanyID,'') AS SupplierCompanyID"),
            Db::raw("CONCAT(outter_stb.BatchID,'') AS BatchID"),
            Db::raw("IFNULL(outter_stb.LimitBuyCount,0) AS LimitBuyCount"),
            Db::raw("IFNULL(outter_stb.Number,0) AS Number"),
            "outter_stb.BatchNo",
            "outter_stb.SpecList",
            Db::raw("IFNULL(outter_stb.CalibrationPeriodTime,'') AS CalibrationPeriodTime"),
            "outter_stb.BatchSpecMinSinglePrice",
            Db::raw("IFNULL(outter_stb.IsDefective,0) AS IsDefective"),
            Db::raw("outter_stb.Number"),
            Db::raw("outter_stb.NumberLock"),
            Db::raw("IFNULL(u_stock.StockRemainNumber,0) AS StockRemainNumber"),
        ];
    }
    
    /**
     * 获取满足优选条件总商品数量
     * @param $subQuery
     */
    public function getBestGoodsCountBySubQuery($subQuery,$receive_data)
    {
        $alias_stock_table = Stockinfo::instance()->getTable();
        $count = Stockinfo::instance()
        ->from($alias_stock_table." as outter_stb")
        ->joinSub($subQuery,"f_stock",function($join){
            $join->on("f_stock.max_stock_id","=","outter_stb.ID");
        })
        ->join("suppliercommodity_s2b as outter_scb","outter_scb.ID","=","outter_stb.SupplierCommodityID")
        ->join("commodityarchives_s2b as outter_com","outter_com.ID","=","outter_stb.CommodityArchivesID")
        ->join("commoditydescription_s2b as cds",function($join){
            $join->on("cds.CommodityInfoID","=","outter_com.ID")
            ->where("cds.IsDeleted",0);
        })
        ->orderBy('outter_scb.ID','ASC')
        ->count();
        return $count;
    }
    
    /**
     * 查询优选分页参数
     * @param int $bid
     * @param $subQuery
     * @param number $page
     * @param number $limit
     */
    public function getBestGoodsPageList($bid,$subQuery,$page, $limit)
    {
        $alias_stock_table = Stockinfo::instance()->getTable();
        $columns = $this->getGoodsColumns();
        return Stockinfo::instance()
        ->from($alias_stock_table." as outter_stb")
        ->select($columns)
        ->joinSub($subQuery,"f_stock",function($join){
            $join->on("f_stock.max_stock_id","=","outter_stb.ID");
        })
        ->leftJoin("stockinfouser_s2b as u_stock",function($join) use($bid) {
            $join->on("u_stock.StockID","=","outter_stb.ID")
            ->where("u_stock.BuID",$bid)
            ->where("u_stock.IsDisable",0)
            ->where("u_stock.StockRemainNumber",'>',0);
        })        
        ->join("suppliercommodity_s2b as outter_scb","outter_scb.ID","=","outter_stb.SupplierCommodityID")
        ->join("commodityarchives_s2b as outter_com","outter_com.ID","=","outter_stb.CommodityArchivesID")
        ->orderBy('outter_scb.ID','asc')
        ->paginate($limit,['*'], 'page', $page,true)
        ->toArray();
    }
    
    /**
     * 查询优选满足条件数据不进行分页
     * @param $subQuery
     * @param number $page
     * @param number $limit
     */
    public function getBestGoodsList($bid,$subQuery)
    {
        $alias_stock_table = Stockinfo::instance()->getTable();
        $columns = $this->getNotifyChangeGoodsColumns();
        return Stockinfo::instance()
        ->from($alias_stock_table." as outter_stb")
        ->select($columns)
        ->joinSub($subQuery,"f_stock",function($join){
            $join->on("f_stock.max_stock_id","=","outter_stb.ID");
        })
        ->leftJoin("stockinfouser_s2b as u_stock",function($join) use($bid) {
            $join->on("u_stock.StockID","=","outter_stb.ID")
            ->where("u_stock.BuID",$bid)
            ->where("u_stock.IsDisable",0)
            ->where("u_stock.StockRemainNumber",'>',0);
        })
        ->join("suppliercommodity_s2b as outter_scb","outter_scb.ID","=","outter_stb.SupplierCommodityID")
        ->join("commodityarchives_s2b as outter_com","outter_com.ID","=","outter_stb.CommodityArchivesID")
        ->get()
        ->toArray();
    }
    
    /**
     * 获取优选模板SQL
     * @param array $where
     */
    public function getBestGoodsQuery( $bid = 0,  $where = [] ,$receive_data)
    {
        //是否有标签管理搜索
        $c_stock_where = $where['c_stock_where'];
        $where = array_merge($where['where'],$where['baseWhere']);
        $alias_stock_table = Stockinfo::instance()->getTable();
        
        $firstSubQuery = Stockinfo::instance()
        ->from($alias_stock_table." as stb")
        ->select([
            "stb.SupplierCommodityID",
            Db::raw("min(stb.BatchSpecMinSinglePrice) AS BatchSpecMinSinglePrice")
        ])
        ->join("suppliercommodity_s2b as scb","stb.SupplierCommodityID","=","scb.ID")
        ->join("suppliercompany_s2b as inner_supplier","inner_supplier.ID","=","stb.SupplierCompanyID")
        ->join("warehouseinfo_s2b as inner_wh","inner_wh.ID","=","stb.WarehouseID")
        ->join("commodityarchives_s2b as com","com.ID","=","stb.CommodityArchivesID")
        ->where("inner_supplier.CompanyStatus",1)
        ->where("inner_supplier.IsBbcCommodity",0)
        ->where("inner_wh.ExamineState",1);
        
        //如果有标签搜索
        if( $receive_data )
        {
            $GoodsTagIDs = [];
            if( $receive_data['GoodsSettingMode'] == self::GOODS_SETTING_MODE_BASE && !empty($receive_data['GoodsBaseSettings']['GoodsTagIDs']) && is_array($receive_data['GoodsBaseSettings']['GoodsTagIDs']) ) {
                $GoodsTagIDs = $receive_data['GoodsBaseSettings']['GoodsTagIDs'];
            } else if( $receive_data['GoodsSettingMode'] == self::GOODS_SETTING_MODE_ADVANCE && !empty($receive_data['GoodsAdvanceSettings']['GoodsTagIDs']) && is_array($receive_data['GoodsAdvanceSettings']['GoodsTagIDs']) ) {
                $GoodsTagIDs = $receive_data['GoodsAdvanceSettings']['GoodsTagIDs'];
            }
            
            if( !empty($GoodsTagIDs) ) 
            {
                $tagSubQuery = SupplierCommodityTag::instance()->select([
                    Db::raw("DISTINCT SupplierCommodityID")
                ])->whereIn('TagID',$GoodsTagIDs);
                $firstSubQuery->joinSub($tagSubQuery,"scb_tag",function($join){
                    $join->on('scb_tag.SupplierCommodityID', '=', 'stb.SupplierCommodityID');
                });
            }
        }
        
        //指定商品导入
        if( isset($receive_data['GoodsSettingMode']) 
            && $receive_data['GoodsSettingMode'] == self::GOODS_SETTING_MODE_ADVANCE 
            && isset($receive_data['GoodsAdvanceSettings']['SupplierChoice']) 
            && isset($receive_data['GoodsAdvanceSettings']['SupplierChoice']['mode']) 
            && $receive_data['GoodsAdvanceSettings']['SupplierChoice']['mode'] == self::SUPPLIER_CHOICE_MODE_WH
        )
        {
            $firstSubQuery->join('commodity_optimization_import as ci',function($join) use ($receive_data) {
                $join->on("ci.SupplierSKUID","=","stb.SupplierCommodityID")->where("ci.BuID",$receive_data['bid']);
            });
            $this->IsImportGoods = true;
        }
        
        $firstSubQuery->whereRaw(implode(" AND ", $where))
        ->groupBy("stb.SupplierCommodityID");
        
        $secondSubQuery = Stockinfo::instance()
        ->from($alias_stock_table." as c_stock")
        ->select([
            Db::raw("max(c_stock.ID) AS max_stock_id")
        ])
        ->joinSub($firstSubQuery,"b_stock",function($join) use ( $c_stock_where ){
            $join->on('b_stock.SupplierCommodityID', '=', 'c_stock.SupplierCommodityID')
            ->on('b_stock.BatchSpecMinSinglePrice','=','c_stock.BatchSpecMinSinglePrice');
            if( $c_stock_where ) {
                $join->whereRaw($c_stock_where);
            }
        })
        ->where(DB::raw("c_stock.Number+c_stock.NumberLock"),'>',0)
        ->groupBy("c_stock.SupplierCommodityID");
        
        return $secondSubQuery;
    }
    
    /**
     * 检查登录
     * @param array $parameters
     */
    public function checkLogin( $parameters = [] )
    {
        if( empty($parameters['token']) ) {
            return Normal::returnCode(Normal::FAIL,"参数token缺失");
        }
        
        if( empty($parameters['requestData']) ) {
            return Normal::returnCode(Normal::FAIL,"参数requestData缺失");
        }
        
        if( !isset($parameters['requestData']['bid']) ) {
            return Normal::returnCode(Normal::FAIL,"参数requestData.bid缺失");
        }
        
        return ManageWsUserAuthService::instance()->checkUserLoginByToken($parameters['token']);
    }
    
    /**
     * 筛选参数处理
     * @param array $param
     */
    public function getWhereParameters( $param = [] )
    {
        $where      = [];
        $_stb_where = [];
        
        if( !empty($param['SkuIDS']) ) {
            $string = implode(",", $param['SkuIDS']);
            $where[] = " com.ID IN ({$string})";
        }
        
        if( !empty($param['SupplierSKUIDS']) ) {
            $string = implode(",", $param['SupplierSKUIDS']);
            $where[] = " scb.ID IN ({$string})";
        }
        
        if( empty($param['GoodsSettingMode']) || !in_array($param['GoodsSettingMode'],[self::GOODS_SETTING_MODE_BASE,self::GOODS_SETTING_MODE_ADVANCE])) {
            return Normal::returnCode(Normal::FAIL,"【基础配置或高级配置必须任选其一！】");
        }
        
        //如果是基础配置
        if( $param['GoodsSettingMode'] == self::GOODS_SETTING_MODE_BASE ) 
        {
            if( empty($param['GoodsBaseSettings']) ) {
                return Normal::returnCode(Normal::FAIL,"【基础配置参数异常】");
            }
            
            $GoodsSettings = $param['GoodsBaseSettings'];
            if( !empty($GoodsSettings['GoodsTypes']) && is_array($GoodsSettings['GoodsTypes']) ) {
                $goodsTypes = implode(",", $GoodsSettings['GoodsTypes']);
                $where[] = "scb.SupplierCommodityType in({$goodsTypes})";
            }
        }
        
        $where_c_stock = '';
        
        //如果是高级配置
        if( $param['GoodsSettingMode'] == self::GOODS_SETTING_MODE_ADVANCE )
        {
            if( empty($param['GoodsAdvanceSettings']) ) {
                return Normal::returnCode(Normal::FAIL,"【高级配置参数异常】");
            }
            
            $GoodsAdvanceSettings = $param['GoodsAdvanceSettings'];
            
            //指定供应商
            if( empty($GoodsAdvanceSettings['SupplierChoice']) ) {
                return Normal::returnCode(Normal::FAIL,"【高级配置参数SupplierChoice异常】");
            }
            
            //确认选择高级模式
            $SupplierChoice = $GoodsAdvanceSettings['SupplierChoice'];
            if( empty($SupplierChoice['mode'] ) ) {
                return Normal::returnCode(Normal::FAIL,"【高级配置参数SupplierChoice.mode缺失】");
            }
            
            if( !in_array($SupplierChoice['mode'],[self::SUPPLIER_CHOICE_MODE_SP,self::SUPPLIER_CHOICE_MODE_WH]) ) {
                return Normal::returnCode(Normal::FAIL,"【高级配置参数SupplierChoice.mode错误】");
            }

            //指定供应商
            if( $SupplierChoice['mode'] == self::SUPPLIER_CHOICE_MODE_SP ) 
            {
                if( empty($SupplierChoice['SupplierChoiceMode']) ) {
                    return Normal::returnCode(Normal::FAIL,"【高级配置参数SupplierChoice.SupplierChoiceMode缺失】");
                }
                
                if( !in_array($SupplierChoice['SupplierChoiceMode'], ['1','2']) ) {
                    return Normal::returnCode(Normal::FAIL,"【高级配置参数SupplierChoice.SupplierChoiceMode错误】");
                }
          
                //非全部选择
                if( $SupplierChoice['SupplierChoiceMode'] == 1 ) 
                {
                    if( empty($SupplierChoice['SupplierList']) ) {
                        return Normal::returnCode(Normal::FAIL,"【高级配置指定供应商情况下，必须至少选择一个供应商！】");
                    }
                    
                    $supplier_list_where = [];
                    foreach ($SupplierChoice['SupplierList'] as $item )
                    {
                        $supplier_where = [];
                        if( !empty($item['SupplierCompanyID']) ) {
                            $supplier_where[] = "stb.SupplierCompanyID = {$item['SupplierCompanyID']}";
                        }
                        
                        if( !empty($item['GoodsTypes']) && is_array($item['GoodsTypes'])) {
                            $GoodsTypes = implode(",", $item['GoodsTypes']);
                            $supplier_where[] = "scb.SupplierCommodityType in({$GoodsTypes})";
                        }
                        
                        if (empty($item['IsSettlement'])){
                            $item['IsSettlement']=1;
                        }
                        
                        if( empty($item['ClassSetting']) ) {
                            return Normal::returnCode(Normal::FAIL,"【高级配置SupplierList.ClassSetting缺失】");
                        }
                        
                        $ClassSetting = $item['ClassSetting'];
                        if( empty($ClassSetting['GoodsClassChoiceMode']) || !in_array($ClassSetting['GoodsClassChoiceMode'], ['1','2'])) {
                            return Normal::returnCode(Normal::FAIL,"【高级配置SupplierList.GoodsClassChoiceMode不正确】");
                        }
                        
                        //GoodsClassChoiceMode= 1 代表选择指定分类
                        $class_where = [];
                        if( $ClassSetting['GoodsClassChoiceMode'] == 1 && !empty($ClassSetting['GoodsClassChoiceList']) ) 
                        {
                            $GoodsClassChoiceList = $ClassSetting['GoodsClassChoiceList'];
                            foreach ($GoodsClassChoiceList as $item )
                            {
                                //当前供应商下的一级分类
                                if( isset($item['classLevel']) && $item['classLevel'] == 1 && !empty($item['classIDs']) && is_array($item['classIDs']) ) {
                                    $classIDs = implode(",",$item['classIDs']);
                                    $class_where[] = "com.FirstClassificationID in({$classIDs})";
                                }
                                
                                //当前供应商下的二级分类
                                if( isset($item['classLevel']) && $item['classLevel'] == 2 && !empty($item['classIDs']) && is_array($item['classIDs']) ) {
                                    $classIDs = implode(",",$item['classIDs']);
                                    $class_where[] = "com.SecondClassificationID in({$classIDs})";
                                }
                                
                                //当前供应商下的三级分类
                                if( isset($item['classLevel']) && $item['classLevel'] == 3 && !empty($item['classIDs']) && is_array($item['classIDs']) ) {
                                    $classIDs = implode(",",$item['classIDs']);
                                    $class_where[] = "com.ThirdClassificationID in({$classIDs})";
                                }
                            }
                        }
                        
                        //判断是否有分类筛选
                        if( $class_where ) {
                            $supplier_where[] = "(". implode(" OR ", $class_where) ." )";
                        }
                        
                        $supplier_list_where[] = "(". implode(" AND ", $supplier_where)." )";
                    }
                    
                    $where[] = "(". implode(" OR ", $supplier_list_where) ." )";
                }
                
                
                //是否包邮
                if( isset($GoodsAdvanceSettings['IsFreeShipping']) && in_array($GoodsAdvanceSettings['IsFreeShipping'],['0','1']) )
                {
                    $IsFreeShipping = (int)$GoodsAdvanceSettings['IsFreeShipping'];
                    $where[] = "scb.IsFreeShipping = {$IsFreeShipping}";
                }
                
                //指定关区
                if( !empty($GoodsAdvanceSettings['GoodsCustoms']) && is_array($GoodsAdvanceSettings['GoodsCustoms']) )
                {
                    $GoodsCustomIDs = implode(",", $GoodsAdvanceSettings['GoodsCustoms']);
                    $where[] = "scb.CustomID in({$GoodsCustomIDs})";
                }
                
                //统一设置库存、校期
                if( !isset($GoodsAdvanceSettings['AllClassSettingMode']) ) {
                    return Normal::returnCode(Normal::FAIL,"【高级配置-库存效期要求设置参数AllClassSettingMode不能为空】");
                }
                
                //设置分类对应条件
                if( $GoodsAdvanceSettings['AllClassSettingMode'] == 2 ) 
                {
                    if( ! empty($GoodsAdvanceSettings['AllClassSettingList']) ) 
                    {
                        $a_c_where = [];
                        foreach ($GoodsAdvanceSettings['AllClassSettingList'] as $item ) 
                        {
                            $c_where = [];
                            if( !empty($item['classID']) ) 
                            {
                                //有库存范围要求
                                if( !empty($item['GoodsStockSetting']) ) {
                                    $GoodsStockSetting = $item['GoodsStockSetting'];
                                    if( !empty($GoodsStockSetting['mode']) && $GoodsStockSetting['mode'] == 2 &&
                                        !empty($GoodsStockSetting['min']) && !empty($GoodsStockSetting['max']) &&
                                        $GoodsStockSetting['max'] > $GoodsStockSetting['min'] && 
                                        $GoodsStockSetting['min'] > 0
                                        )
                                    {
                                        $c_where[] = "(stb.Number >= {$GoodsStockSetting['min']} AND stb.Number <= {$GoodsStockSetting['max']})";
                                        $this->IsStockNumberLimit = true;
                                    }
                                }
                                
                                //有效期要求
                                if( !empty($item['PeriodSetting']) ) {
                                    $PeriodSetting = $item['PeriodSetting'];
                                    if( !empty($PeriodSetting['mode']) && $PeriodSetting['mode'] == 2 &&
                                        !empty($PeriodSetting['months']) && !empty($PeriodSetting['months']) &&
                                        $PeriodSetting['months'] > 0
                                        )
                                    {
                                        $months = $PeriodSetting['months'];
                                        $current_month = date("Y-m-d 00:00:00"); 
                                        $strtime = strtotime("+ {$months} Month");
                                        $feature_date = date("Y-m-d",$strtime);
                                        $c_where[] = "((stb.CalibrationPeriodTime >= '{$feature_date}' AND stb.IsHasPeriodTime =1) or stb.IsHasPeriodTime = 0 )";
                                        $this->IsGoodsExpireLimit = true;
                                    }
                                }

                                //有商品类型要求
                                if( !empty($item['shopTypeSetting']) ) {
                                    $GoodsTypesSetting = $item['shopTypeSetting'];
                                    if(!empty($GoodsTypesSetting['mode']) && $GoodsTypesSetting['mode'] == 2 &&
                                        !empty($GoodsTypesSetting['shopType'])){
                                        if (count($GoodsTypesSetting['shopType'])==1){
                                            $GoodsType=current($GoodsTypesSetting['shopType']);
                                            $c_where[]="(scb.SupplierCommodityType={$GoodsType})";
                                        } else {
                                            $GoodsType=implode(',',$GoodsTypesSetting['shopType']);
                                            $c_where[]="(scb.SupplierCommodityType in ({$GoodsType}))";
                                        }
                                    }
                                }
                                
                                //二级分类
                                $c_where[] = "com.SecondClassificationID='{$item['classID']}'";
                            }
                            
                            if( $c_where ) {
                                $a_c_where[] = "(". implode(" AND ", $c_where) ." )";
                            }
                        }
                        
                        if( $a_c_where ) {
                            $_sql_where = "(". implode(" OR ", $a_c_where) ." )";
                            //$where_c_stock = str_replace("stb.", "c_stock.", $_sql_where);
                            $where[] = $_sql_where;
                        }
                    }
                } else {
                    
                    //统一设置
                    if( empty($GoodsAdvanceSettings['GlobalClassSetting']) ) {
                        return Normal::returnCode(Normal::FAIL,"【高级配置-库存效期要求设置参数统一设置GlobalClassSetting不能为空】");
                    }
                    
                    $GlobalClassSetting = $GoodsAdvanceSettings['GlobalClassSetting'];
                    $c_where = [];
                    
                    //有库存范围要求
                    if( !empty($GlobalClassSetting['GoodsStockSetting']) ) {
                        $GoodsStockSetting = $GlobalClassSetting['GoodsStockSetting'];
                        if( !empty($GoodsStockSetting['mode']) && $GoodsStockSetting['mode'] == 2 &&
                            !empty($GoodsStockSetting['min']) && !empty($GoodsStockSetting['max']) &&
                            $GoodsStockSetting['max'] > $GoodsStockSetting['min'] && 
                            $GoodsStockSetting['min'] > 0
                            )
                        {
                            $c_where[] = "(stb.Number >= {$GoodsStockSetting['min']} AND stb.Number <= {$GoodsStockSetting['max']})";
                            $this->IsStockNumberLimit = true;
                        }
                    }
                    
                    //有效期要求
                    if( !empty($GlobalClassSetting['PeriodSetting']) ) {
                        $PeriodSetting = $GlobalClassSetting['PeriodSetting'];
                        if( !empty($PeriodSetting['mode']) && $PeriodSetting['mode'] == 2 &&
                            !empty($PeriodSetting['months']) && !empty($PeriodSetting['months']) &&
                            $PeriodSetting['months'] > 0
                            )
                        {
                            $months = $PeriodSetting['months'];
                            $current_month = date("Y-m-d 00:00:00");
                            $strtime = strtotime("+ {$months} Month");
                            $feature_date = date("Y-m-d",$strtime);
                            $_sql_where = "((stb.CalibrationPeriodTime >= '{$feature_date}' AND stb.IsHasPeriodTime =1) or stb.IsHasPeriodTime = 0 )";
                            $c_where[] = $_sql_where;
                            $where_c_stock = str_replace("stb.", "c_stock.", $_sql_where);
                            $this->IsGoodsExpireLimit = true;
                        }
                    }

                    //有商品类型要求
                    if( !empty($GlobalClassSetting['shopTypeSetting']) ) {
                        $GoodsTypesSetting = $GlobalClassSetting['shopTypeSetting'];
                        if(!empty($GoodsTypesSetting['mode']) && $GoodsTypesSetting['mode'] == 2 &&
                            !empty($GoodsTypesSetting['shopType'])){
                            if (count($GoodsTypesSetting['shopType'])==1){
                                $GoodsType=current($GoodsTypesSetting['shopType']);
                                $c_where[]="(scb.SupplierCommodityType={$GoodsType})";
                            } else {
                                $GoodsType=implode(',',$GoodsTypesSetting['shopType']);
                                $c_where[]="(scb.SupplierCommodityType in ({$GoodsType}))";
                            }
                        }
                    }
                    
                    if( $c_where ) {
                        $where[] = "(". implode(" AND ", $c_where) ." )";
                    }
                }
            }
        }
        
        //基础条件（未删除、已上架、有库存、价格大于0、主档案启用）
        $baseWhere = [];
        $baseWhere[] = "scb.IsDeleted = 0";
        $baseWhere[] = "scb.SaleType = 1";
        $baseWhere[] = "scb.UpstreamSaleType = 1";
        $baseWhere[] = "stb.BatchSpecMinSinglePrice > 0 ";
        $baseWhere[] = "(stb.Number + stb.NumberLock) > 0 ";
        $baseWhere[] = "stb.IsHasPrice = 1 ";
        $baseWhere[] = "stb.IsDeleted = 0 ";
        $baseWhere[] = "com.IsDeleted = 0 ";
        $baseWhere[] = "com.IsForbidden = 0 ";
        $baseWhere[] = "com.IsUseAble = 1 ";
        return Normal::returnCode(Normal::SUC,"OK",[
            'stb_where' => $_stb_where,
            'where'     => $where,
            'baseWhere' => $baseWhere,
            'c_stock_where' => $where_c_stock
        ]);
    }
}